"""
@File    :   in.py
@Time    :   2024/03/24 22:10:55
@Author  :   Qrj
@Email   :   923207736@qq.com
@description   :   用户相关的pydantic验证模型
"""

from datetime import datetime
from ipaddress import IPv4Network

from pydantic import BaseModel, Field, conint, field_serializer

from src.business.admin.system.user.enums import UserSexEnum
from src.config import get_app_settings
from src.schemas.custom_field import CustomErrorMsgEmailStr
from src.schemas.serializer_func import ipv4_network_list_serializer
from src.schemas.validate import (
    BaseSearchValidateSchemaMixin,
    BaseValidateSchemaConfigMixin,
)

settings = get_app_settings()


class UserCreateValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于创建用户的验证模型"""

    username: str = Field(
        default=..., min_length=1, max_length=20, description="用户名"
    )
    password: str = Field(
        default=..., min_length=1, max_length=20, description="密码明文"
    )
    name: str = Field(
        default=..., min_length=1, max_length=50, description="使用人姓名"
    )
    sex: UserSexEnum = Field(default=UserSexEnum.unknown.value, description="用户性别")
    status: bool = Field(default=True, description="状态")
    remark: str = Field(default="", min_length=1, max_length=300, description="备注")
    phone: str = Field(
        default="",
        pattern=r"^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$",
        min_length=1,
        max_length=50,
        description="手机号码",
    )
    email: CustomErrorMsgEmailStr = Field(
        default="", min_length=1, max_length=100, description="邮箱"
    )
    can_login_ip_network: list[IPv4Network] = Field(
        default_factory=list, description="允许登录的IP段列表"
    )
    number_of_simultaneous_logins: int = Field(
        default=1, ge=1, le=1000, description="用户可同时登录数量"
    )
    password_modification_deadline: int = Field(
        default=90, ge=0, le=3650, description="密码修改期限(天)"
    )
    # 字段序列化
    serializer_can_login_ip_network = field_serializer(
        "can_login_ip_network", when_used="always"
    )(ipv4_network_list_serializer)


class UserSelfUpdateInfoValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于用户修改自身信息的验证模型"""

    name: str = Field(
        default=..., min_length=1, max_length=50, description="使用人姓名"
    )
    sex: UserSexEnum = Field(default=UserSexEnum.unknown.value, description="用户性别")
    phone: str = Field(
        default="",
        pattern=r"^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$",
        min_length=1,
        max_length=50,
        description="手机号码",
    )
    email: CustomErrorMsgEmailStr = Field(
        default="", min_length=1, max_length=100, description="邮箱"
    )


class UserSelfUpdateAvatarValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于用户修改自身头像的验证模型"""

    avatar: str = Field(
        default=settings.default_user_avatar,
        min_length=1,
        max_length=300,
        description="头像",
    )


class UserSelfUpdatePasswordValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于用户修改自身密码的验证模型"""

    password: str = Field(
        default=..., min_length=1, max_length=20, description="密码明文"
    )


class UserUpdateValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于修改用户信息的验证模型"""

    id: int = Field(default=..., ge=1, description="主键")
    name: str = Field(
        default=..., min_length=1, max_length=50, description="使用人姓名"
    )
    sex: UserSexEnum = Field(default=UserSexEnum.unknown.value, description="用户性别")
    status: bool = Field(default=True, description="状态")
    remark: str = Field(default="", min_length=1, max_length=300, description="备注")
    phone: str = Field(
        default="",
        pattern=r"^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$",
        min_length=1,
        max_length=50,
        description="手机号码",
    )
    email: CustomErrorMsgEmailStr = Field(
        default="", min_length=1, max_length=100, description="邮箱"
    )
    can_login_ip_network: list[IPv4Network] = Field(
        default_factory=list, description="允许登录的IP段列表"
    )
    number_of_simultaneous_logins: int = Field(
        default=1, ge=1, le=1000, description="用户可同时登录数量"
    )
    password_modification_deadline: int = Field(
        default=90, ge=0, le=3650, description="密码修改期限(天)"
    )
    # 序列化器
    serializer_can_login_ip_network = field_serializer(
        "can_login_ip_network", when_used="always"
    )(ipv4_network_list_serializer)


class UserUpdateStatusValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于单独修改用户状态的验证模型"""

    id: int = Field(default=..., ge=1, description="主键")
    status: bool = Field(default=..., description="状态")  # (True正常 False停用)


class UserResetPasswordValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于重置用户密码的验证模型"""

    id: int = Field(default=..., ge=1, description="主键")
    password: str = Field(
        default=..., min_length=1, max_length=20, description="密码明文"
    )


class UserAssignRoleValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于分配用户角色的验证模型"""

    id: int = Field(default=..., ge=1, description="主键")
    role_ids: list[conint(ge=1)] = Field(
        default_factory=list, description="分配的角色ID列表"
    )


class UserDeleteValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于删除用户的验证模型"""

    ids: list[conint(ge=1)] = Field(
        default=..., min_length=1, description="需删除的主键列表"
    )


class UserListSearchValidateSchema(BaseModel, BaseSearchValidateSchemaMixin):
    """用于查询用户列表的验证模型"""

    username: str | None = Field(
        default=None,
        description="用户名",
        min_length=1,
        max_length=20,
        json_schema_extra={"str_like_search_type": "complete"},
    )
    phone: str | None = Field(
        default=None, min_length=1, max_length=50, description="手机号码"
    )
    email: str | None = Field(
        default=None, min_length=1, max_length=100, description="邮箱"
    )
    name: str | None = Field(
        default=None,
        description="使用人姓名",
        min_length=1,
        max_length=50,
        json_schema_extra={"str_like_search_type": "complete"},
    )
    sex: UserSexEnum | None = Field(default=None, description="用户性别")
    remark: str | None = Field(
        default=None,
        description="备注",
        min_length=1,
        max_length=300,
        json_schema_extra={"str_like_search_type": "complete"},
    )
    status: bool | None = Field(default=None, description="状态")
    is_admin: bool | None = Field(default=None, description="是否管理员用户")
    create_datetime: tuple[datetime, datetime] | None = Field(
        default=None, description="创建时间"
    )
    creator_username: str | None = Field(
        default=None,
        min_length=1,
        max_length=20,
        description="创建者用户名",
        json_schema_extra={"str_like_search_type": "complete"},
    )
    updater_username: str | None = Field(
        default=None,
        min_length=1,
        max_length=20,
        description="修改者用户名",
        json_schema_extra={"str_like_search_type": "complete"},
    )
    number_of_simultaneous_logins: tuple[
        conint(ge=1, le=1000), conint(ge=1, le=1000)
    ] | None = Field(default=None, description="用户可同时登录数量")
    password_modification_deadline: tuple[
        conint(ge=0, le=3650), conint(ge=0, le=3650)
    ] | None = Field(default=None, description="密码修改期限(天)")
    # last_login_ip: str | None = Field(
    #     default=None,
    #     min_length=1,
    #     max_length=20,
    #     description="最后登录IP",
    #     json_schema_extra={"str_like_search_type": "complete"},
    # )
    last_login_datetime: tuple[datetime, datetime] | None = Field(
        default=None,
        description="最后登录时间",
        json_schema_extra={"allow_order": True},
    )
    admin_last_modified_datetime: tuple[datetime, datetime] | None = Field(
        default=None,
        description="管理员最后修改用户信息的时间",
        json_schema_extra={"allow_order": True},
    )
    admin_pwd_last_reset_datetime: tuple[datetime, datetime] | None = Field(
        default=None,
        description="管理员最后重置密码的时间",
        json_schema_extra={"allow_order": True},
    )
    self_info_last_modified_datetime: tuple[datetime, datetime] | None = Field(
        default=None,
        description="用户自身最后修改信息的时间",
        json_schema_extra={"allow_order": True},
    )
    self_psw_last_modified_datetime: tuple[datetime, datetime] | None = Field(
        default=None,
        description="用户自身密码最后修改时间",
        json_schema_extra={"allow_order": True},
    )
